package com.bluebench.bigul.domain.graphics.simple.polygon;

import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;

import com.bluebench.bigul.domain.graphics.Graphic;
import com.bluebench.bigul.domain.graphics.Line;
import com.bluebench.bigul.domain.graphics.Point;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.pdf.PdfContentByte;

public class Square extends Quadilateral implements EquiPolygon{
	
	public Square() {
		
	}
		
	public Square(PdfContentByte canvas) {
		super(canvas);		
	}

	/**
	 * generates polygons with same sides
	 */
	@Override
	public Polygon build(Point start, float side) {
		float x = start.getX();
		float y = start.getY();
		addVertex(start);
		addSide(new Line(side));
		canvas.moveTo(x,y);        
        canvas.lineTo(x + side, y);
        addVertex(new Point(x + side, y));
        canvas.lineTo(x + side, y + side);
        addVertex(new Point(x + side, y + side));
        canvas.lineTo(x, y + side);
        addVertex(new Point(x, y + side));
       	return this;
	}
	
	/**
	 * Generates polygons with different sides and lower left corner
	 */
	@Override
	public Polygon build(Point start, List<Float> sides) {
		
		List<Line> lines = new ArrayList<Line>();
		for(float s : sides){
			Line l = new Line(s);
			lines.add(l);
		}
		
		this.sides = lines;
		
		if(validate()){
			build(start,sides.get(0));        
		}
       	return this;	
	}

	@Override
	protected boolean validate() {		
		
		if(vertices!=null && (!vertices.isEmpty()) && vertices.size()==4){
			
			Point A = vertices.get(0);
			Point B = vertices.get(1);
			Point C = vertices.get(2);
			Point D = vertices.get(3);
			
			double s1Sqr = Math.pow((A.getX()-B.getX()),2) + Math.pow((A.getY()-B.getY()),2);
			double s2Sqr = Math.pow((B.getX()-C.getX()),2) + Math.pow((B.getY()-C.getY()),2);
			double s3Sqr = Math.pow((C.getX()-D.getX()),2) + Math.pow((C.getY()-D.getY()),2);
			double s4Sqr = Math.pow((D.getX()-A.getX()),2) + Math.pow((D.getY()-A.getY()),2);
						
			double diagonal1Square = Math.pow((Math.ceil(A.getX())-Math.ceil(C.getX())),2) + Math.pow(( Math.ceil(A.getY())-Math.ceil(C.getY())),2);
			double diagonal2Square = Math.pow((Math.ceil(D.getX())-Math.ceil(B.getX())),2) +  Math.pow((Math.ceil(D.getY())-Math.ceil(B.getY())),2);			
			 
			if(s1Sqr==s2Sqr && s2Sqr==s3Sqr && s3Sqr==s4Sqr && diagonal1Square==diagonal2Square){
				return true;
			}else{
				System.out.println("validation fails");
				return false;
			}
			
		}else if(sides!=null && sides.size()==4){
			
			if(sides.get(0).getLength()==sides.get(1).getLength() && sides.get(1).getLength()==sides.get(2).getLength() && sides.get(2).getLength()==sides.get(3).getLength() && sides.get(3).getLength()==sides.get(1).getLength()){
			  return true;
			}			
			return false;
			
		}else{			
			return false;
			
		}
	}

	@Override
	public Graphic concentric(float distance, boolean in) {
		float x = vertices.get(0).getX();
		float y = vertices.get(0).getY();
		Point start=null;
		float side=0;
		if(in){
			start = new Point(x+distance,y+distance);
			//TODO : validate that lenght > 2d
			side = sides.get(0).getLength() - (2*distance);
		}else{
			start = new Point(x-distance,y-distance);
			//TODO : validate that lenght > 2d
			side = sides.get(0).getLength() + (2*distance);
		}
		return build(start,side);
	}

	@Override
	public Polygon build(Point start, float side, float rotation) {
		float x0 = start.getX();
		float y0 = start.getY();
		Point pivot = new Point(x0+(side/2),y0+(side/2));
		Point p0_rotate =  getRotation(start, pivot, rotation);
		
		float x1 = x0 +side;
		float y1 = y0;
		Point p1_rotate = getRotation(new Point(x1,y1), pivot, rotation);
		
		float x2 = x1;
		float y2 = y1 + side;
		Point p2_rotate = getRotation(new Point(x2,y2), pivot, rotation);
		
		float x3 = x0;
		float y3 = y2;
		Point p3_rotate = getRotation(new Point(x3,y3), pivot, rotation);
		
		addVertex(p0_rotate);
		addVertex(p1_rotate);
		addVertex(p2_rotate);
		addVertex(p3_rotate);
		
		build();
		
		return this;
	}
	
		
	
	@Override
	public Graphic copy(float distance, int direction) {
		
		float x = vertices.get(3).getX();
		float y = vertices.get(3).getY();
		float side = sides.get(0).getLength();
		
			float x_new = 0;
			float y_new = 0;

			switch(direction){
			
				case LEFT:
					x_new = x - distance;
					if(x_new<0){
						//TODO : throw Exception 
					}
					y_new = y;
					break;
				case RIGHT:
					x_new = x + distance;
					y_new = y;
					break;
				case TOP:
					y_new = y + distance;
					x_new = x;
					break;
				case BOTTOM:
					y_new = y - distance;
					if(y_new<0){
						//TODO : throw Exception 
					}
					x_new = x;
					break;
				default:
					//throw exception				
			
			}
			build(new Point(x_new,y_new),side);
			
		
		return this;
	}
	
	
}
